package ma.xin.shi;

import java.io.BufferedReader;
import java.io.File;
//import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.net.URL;
//import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
//import org.eclipse.jface.window.ApplicationWindow;
//import org.eclipse.swt.widgets.DirectoryDialog;
//import ma.xin.shi.arxml.export.cherySomeip.matrix.CherySomeipArxmlExport;
import ma.xin.shi.arxml.export.cherySomeip.CherySomeipArxmlExportMain;
import ma.xin.shi.arxml.load.cherySomeip.CherySomeipArxmlLoadMain;

public class MainApp {
    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setSize(1400, 1050); // 设置窗口大小
        shell.setText("LYAutosarTool_V1.0.0"); // 设置窗口标题

        // 设置主窗口布局为 GridLayout
        shell.setLayout(new GridLayout(1, false));

        // 创建工具栏
        createToolBar(shell);

        // 创建状态栏
        Text statusBar = createStatusBar(shell);

        // 创建分割区域：左侧菜单栏 + 右侧工作区
        createMainArea(shell, statusBar);

        // 打开窗口
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }

    /**
     * 创建工具栏
     */
    private static void createToolBar(Shell shell) {
        ToolBar toolBar = new ToolBar(shell, SWT.FLAT);
        toolBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        // File button with dropdown menu
        ToolItem fileToolItem = new ToolItem(toolBar, SWT.PUSH);
        fileToolItem.setText("File");
        fileToolItem.addSelectionListener(createFileMenuDropdown(shell, fileToolItem));

        // Project button
        ToolItem projectToolItem = new ToolItem(toolBar, SWT.PUSH);
        projectToolItem.setText("Project");
        projectToolItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
                messageBox.setText("Project");
                messageBox.setMessage("You clicked the project button.");
                messageBox.open();
            }
        });

        // Load button
        ToolItem loadToolItem = new ToolItem(toolBar, SWT.PUSH);
        loadToolItem.setText("Load");
        loadToolItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                FileDialog dialog = new FileDialog(shell, SWT.OPEN);
                dialog.setFilterExtensions(new String[] { "*.txt", "*.*" });
                String filePath = dialog.open();
                if (filePath != null) {
                    System.out.println("Loaded file: " + filePath);
                    // 在这里实现加载文件的逻辑
                }
            }
        });

        // Save button
        ToolItem saveToolItem = new ToolItem(toolBar, SWT.PUSH);
        saveToolItem.setText("Save");
        saveToolItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
                messageBox.setText("Save");
                messageBox.setMessage("You clicked the Save button.");
                messageBox.open();
            }
        });
        
        // Generate button
        ToolItem genToolItem = new ToolItem(toolBar, SWT.PUSH);
        genToolItem.setText("Generate");
        genToolItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
            	handleGenerateCPlusCode(shell);
            }
        });
    }

    /**
     * 创建状态栏
     */
    private static Text createStatusBar(Shell shell) {
        Text statusBar = new Text(shell, SWT.READ_ONLY | SWT.BORDER);
        statusBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        //statusBar.setText("Status: Ready");
        return statusBar;
    }

    /**
     * 创建主区域：左侧菜单栏 + 右侧工作区
     */
    private static Composite createMainArea(Shell shell, Text statusBar) {
        Composite mainArea = new Composite(shell, SWT.NONE);
        mainArea.setLayout(new GridLayout(2, false));
        mainArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        // 左侧菜单栏
        Composite menuPanel = new Composite(mainArea, SWT.BORDER);
        menuPanel.setLayout(new GridLayout(1, false));
        menuPanel.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
        menuPanel.setBackground(mainArea.getDisplay().getSystemColor(SWT.COLOR_WHITE));

        // 右侧工作区
        final Composite workArea = new Composite(mainArea, SWT.BORDER);
        workArea.setLayout(new GridLayout(1, false));
        workArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        // 添加 DataType 按钮
        Button dataTypeButton = new Button(menuPanel, SWT.PUSH);
        dataTypeButton.setText("DataType");
        dataTypeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        dataTypeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                statusBar.setText("Now in DataType Page");
                updateWorkArea(workArea, "Displaying DataType Content");
                DataTypeDisplay.display(workArea);
            }
            
        });

        // 添加 Service 按钮
        Button serviceButton = new Button(menuPanel, SWT.PUSH);
        serviceButton.setText("Service");
        serviceButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        serviceButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                statusBar.setText("Now in Service Page");
                ServiceDisplay.display(workArea);
            }
        });

        // 添加 ECU 按钮
        Button ecuButton = new Button(menuPanel, SWT.PUSH);
        ecuButton.setText("ECU");
        ecuButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        ecuButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                statusBar.setText("Now in ECU Page");
                EcuDisplay.display(workArea);
            }
        });
/*
        // 添加 COMM 按钮
        Button commButton = new Button(menuPanel, SWT.PUSH);
        commButton.setText("CM");
        commButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        commButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                statusBar.setText("Now in COMM Page");
                CommDisplay.display(workArea);
            }
        });
*/
        // 添加 Someip action 按钮
        Button someipActButton = new Button(menuPanel, SWT.PUSH);
        someipActButton.setText("SomeipAction");
        someipActButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        someipActButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                statusBar.setText("Now in Someip Action Page");
                SomeipActionDisplay.display(workArea);
            }
        });

        // 默认加载 DataType 页面内容
        statusBar.setText("Now in DataType Page");
        updateWorkArea(workArea, "Displaying DataType Content");
        DataTypeDisplay.display(workArea);

        return mainArea;
    }

    /**
     * 更新工作区内容
     */
    private static void updateWorkArea(Composite workArea, String contentText) {
        // 清除现有控件
        Control[] children = workArea.getChildren();
        for (Control child : children) {
            child.dispose();
        }

        // 添加新内容
        Label contentLabel = new Label(workArea, SWT.NONE);
        contentLabel.setText(contentText);
        contentLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));

        // 强制重新布局
        workArea.layout();
        workArea.getParent().layout(); // 确保父容器也重新布局
    }

    private static SelectionListener createFileMenuDropdown(final Shell shell, final ToolItem toolItem) {
        return new SelectionAdapter() {
            private Menu fileMenu;

            @Override
            public void widgetSelected(SelectionEvent e) {
                // 如果菜单不存在或者已经被销毁，就重新创建
                if (fileMenu == null || fileMenu.isDisposed()) {
                    // 使用 SWT.POP_UP 样式创建菜单
                    fileMenu = new Menu(shell, SWT.POP_UP);

                    // 菜单项：Save As ARXML
                    MenuItem saveAsArxmlItem = new MenuItem(fileMenu, SWT.PUSH);
                    saveAsArxmlItem.setText("Save As ARXML");
                    saveAsArxmlItem.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent event) {
                            handleSaveAsARXML(shell);
                        }
                    });

                    // 菜单项：Save As JSON（预留）
                    MenuItem loadCherySomeipArxml = new MenuItem(fileMenu, SWT.PUSH);
                    loadCherySomeipArxml.setText("Load Arxml");
                    loadCherySomeipArxml.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent event) {
                        	loadCherySomeipArxml(shell);
                        }
                    });
                    
                    // 菜单项：Save As JSON（预留）
                    MenuItem saveAsJsonItem = new MenuItem(fileMenu, SWT.PUSH);
                    saveAsJsonItem.setText("Save As JSON");
                    saveAsJsonItem.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent event) {
                            handleSaveAsJSON(shell);
                        }
                    });
                }

                // 获取按钮位置并弹出菜单
                Rectangle bounds = toolItem.getBounds();
                Point location = toolItem.getParent().toDisplay(new Point(bounds.x, bounds.y + bounds.height));
                fileMenu.setLocation(location.x, location.y);
                fileMenu.setVisible(true);
            }
        };
    }

    private static void handleSaveAsARXML(Shell shell) {
        // 使用 FileDialog 允许用户选择完整路径 + 文件名
        FileDialog fileDialog = new FileDialog(shell, SWT.SAVE);
        fileDialog.setText("保存 ARXML 文件");
        fileDialog.setFilterExtensions(new String[] { "*.arxml" }); // 设置过滤器
        fileDialog.setFileName("mxs.arxml"); // 默认文件名

        String filePath = fileDialog.open();

        String outputPath;
        if (filePath != null && !filePath.isEmpty()) {
            // 用户选择了路径和文件名
            outputPath = filePath;
        } else {
            // 用户取消操作，使用默认路径 D:/mxs.arxml
            outputPath = "D:/mxs.arxml";
        }

        try {
            // 确保父目录存在
            File file = new File(outputPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            // 获取配置管理器实例
            ConfigurationManager configManager = ConfigurationManager.getInstance();

            // 调用统一导出入口
            CherySomeipArxmlExportMain.generateArxml(outputPath, configManager);

            // 提示用户保存成功
            MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
            messageBox.setText("导出成功");
            messageBox.setMessage("ARXML 文件已生成至：" + outputPath);
            messageBox.open();

        } catch (Exception e) {
            // 捕获并显示错误信息
            MessageBox errorBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
            errorBox.setText("导出失败");
            errorBox.setMessage("导出 ARXML 时发生错误：\n" + e.getMessage());
            errorBox.open();
            e.printStackTrace();
        }
    }
    
    private static void handleGenerateCPlusCode(Shell shell) {
        // 1. 选择输出目录
        DirectoryDialog dirDialog = new DirectoryDialog(shell, SWT.NONE);
        dirDialog.setText("选择输出目录");
        dirDialog.setMessage("请选择 ARXML 和 C++ 代码的生成目录");
        String selectedDirPath = dirDialog.open();
        if (selectedDirPath == null) return;

        File outputDir = new File(selectedDirPath);
        String arxmlPath = new File(outputDir, "config.arxml").getAbsolutePath();

        // 2. 确保目录存在
        if (!outputDir.exists()) outputDir.mkdirs();

        try {
            // 3. 生成 ARXML
            ConfigurationManager configManager = ConfigurationManager.getInstance();
            CherySomeipArxmlExportMain.generateArxml(arxmlPath, configManager);

            // 4. 提取 createcodeconfig.exe 到 outputDir（不是临时目录！）
            File exeFile = new File(outputDir, "createcodeconfig.exe");
            extractResource("/gen_code/createcodeconfig.exe", exeFile);

            // 5. 提取 default_serialization_props_origin 到 outputDir            
            File propsFile = new File(outputDir, "default_serialization_props_origin");
            extractResource("/gen_code/default_serialization_props_origin", propsFile);

            // 6. 准备命令：exe 在 outputDir，所以可以直接运行
            List<String> command = new ArrayList<>();
            command.add(exeFile.getAbsolutePath());          // 完整路径
            command.add("config.arxml");                     // 相对路径（在 outputDir）
            command.add("code");                             // 输出目录名
            command.add(".");                                // 当前目录（找 props）
            


            // 7. 执行命令
            ProcessBuilder pb = new ProcessBuilder(command);
            pb.directory(outputDir);                         // 工作目录 = outputDir
            pb.redirectErrorStream(true);

            Process process = pb.start();

            // 读取日志
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("[EXE] " + line);
            }

            int exitCode = process.waitFor();

            if (exitCode == 0) {
                MessageBox done = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
                done.setText("生成成功");
                done.setMessage("ARXML 和 C++ 代码已生成！\n路径：" + outputDir.getAbsolutePath());
                done.open();
            } else {
                MessageBox error = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
                error.setText("生成失败");
                error.setMessage("C++ 代码生成工具返回错误码：" + exitCode);
                error.open();
            }

        } catch (Exception e) {
            e.printStackTrace();
            MessageBox error = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
            error.setText("生成失败");
            error.setMessage("发生错误：" + e.getMessage());
            error.open();
        }
    }

    /**
     * 从 resources 提取文件到指定 File
     */
    private static void extractResource(String resourcePath, File targetFile) throws IOException {
        InputStream in = MainApp.class.getResourceAsStream(resourcePath);
        if (in == null) {
            throw new IOException("Resource not found: " + resourcePath);
        }
        Files.copy(in, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        in.close();
        targetFile.setExecutable(true); // Windows 忽略，但无害
    }

    /**
     * 从 resources 中提取文件到临时目录
     */
    public static File extractResource(String resourcePath, String fileName) throws IOException {
        InputStream in = MainApp.class.getResourceAsStream(resourcePath);
        if (in == null) {
            throw new IOException("Resource not found: " + resourcePath);
        }

        File tempDir = new File(System.getProperty("java.io.tmpdir"), "someip-tool/gen_code");
        tempDir.mkdirs();

        File extractedFile = new File(tempDir, fileName);
        Files.copy(in, extractedFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        in.close();

        extractedFile.setExecutable(true); // 对 Unix 系统有效，Windows 忽略
        return extractedFile;
    }

    /**
     * 递归复制文件或目录
     */
    private static void copyDirectory(File source, File target) throws IOException {
        if (source.isDirectory()) {
            if (!target.exists()) {
                target.mkdirs();
            }

            File[] files = source.listFiles(); // 用 listFiles() 替代 list()
            if (files == null) {
                throw new IOException("无法读取目录: " + source.getAbsolutePath());
            }

            for (File file : files) {
                File dest = new File(target, file.getName());
                copyDirectory(file, dest); // 递归
            }
        } else {
            // 是文件，复制内容
            if (target.exists()) {
                target.delete(); // 避免“拒绝访问”
            }
            Files.copy(source.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private static void handleSaveAsJSON(Shell shell) {
        MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
        messageBox.setText("Save As JSON");
        messageBox.setMessage("该功能尚未实现，敬请期待！");
        messageBox.open();
    }

    private static void loadCherySomeipArxml(Shell shell) {
        FileDialog dialog = new FileDialog(shell, SWT.OPEN);
        dialog.setText("选择 ARXML 文件");
        dialog.setFilterExtensions(new String[] {"*.arxml"});
        dialog.setFilterNames(new String[] {"ARXML 文件 (*.arxml)"});

        String filePath = dialog.open();

        if (filePath == null || filePath.isEmpty()) {
            return;
        }

        // 只需一行代码触发整个解析流程
        new CherySomeipArxmlLoadMain().loadArxmlFile(filePath);
    }

}